/*
 * Copyright (c) 2009 Roman Savelyev
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "testconuiterm.h"
#include "conuiterminal.h"
#include <ecom.h>
#include <e32cons.h>

_LIT8(KTerminalType, "TEXTSHELLTERMINAL");

CTestConUiTerm::CTestConUiTerm(const TDesC8& aSuiteName) : CxxTest::TestSuite(aSuiteName)
    {}

void CTestConUiTerm::setUp()
    {
    static const TUint KTimeoutMicroseconds = 10000000;
    iTerminal = CConUiTerminal::NewL(KTerminalType);
    User::LeaveIfError(iTimer.CreateLocal());
    iTimerStatus = KRequestPending;
    iTimer.After(iTimerStatus, KTimeoutMicroseconds);
    }

void CTestConUiTerm::tearDown()
    {
    iTimer.Cancel();
    iTimer.Close();
    delete iTerminal;
    REComSession::FinalClose();
    }

void CTestConUiTerm::testSurfaceSize()
    {
    CConsoleBase* reference = Console::NewL(KNullDesC, TSize(KConsFullScreen, KConsFullScreen));
    CleanupStack::PushL(reference);
    TSize referenceSize = reference->ScreenSize();
    TSize surfaceSize = iTerminal->SurfaceSizeL();
    TS_ASSERT_EQUALS(surfaceSize.iHeight, referenceSize.iHeight);
    TS_ASSERT_EQUALS(surfaceSize.iWidth, referenceSize.iWidth);
    CleanupStack::PopAndDestroy(reference);
    }

void CTestConUiTerm::testReadKey()
    {
    iTerminal->WriteL(_L("Press any key to perform test..."));
    TConsoleKey key;
    TRequestStatus status = KRequestPending;
    iTerminal->ReadKey(key, status);
    User::WaitForRequest(status, iTimerStatus);
    TS_ASSERT_EQUALS(iTimerStatus.Int(), KRequestPending);
    TS_ASSERT_EQUALS(status.Int(), KErrNone);
    }

void CTestConUiTerm::testReadKeyCancel()
    {
    iTerminal->WriteL(_L("Dont press anything..."));
    TConsoleKey key;
    TRequestStatus status = KRequestPending;
    iTerminal->ReadKey(key, status);
    iTerminal->ReadKeyCancel();
    User::WaitForRequest(status, iTimerStatus);
    TS_ASSERT_EQUALS(iTimerStatus.Int(), KRequestPending);
    TS_ASSERT_EQUALS(status.Int(), KErrCancel);
    }

void CTestConUiTerm::testWrite()
    {
    iTerminal->WriteL(_L("Press any key if you can read this..."));
    TConsoleKey key;
    TRequestStatus status = KRequestPending;
    iTerminal->ReadKey(key, status);
    User::WaitForRequest(status, iTimerStatus);
    TS_ASSERT_EQUALS(iTimerStatus.Int(), KRequestPending);
    TS_ASSERT_EQUALS(status.Int(), KErrNone);
    }

void CTestConUiTerm::testHideCursor()
    {
    iTerminal->HideCursorL();
    iTerminal->WriteL(_L("No cursor. Press any key if true..."));
    TConsoleKey key;
    TRequestStatus status = KRequestPending;
    iTerminal->ReadKey(key, status);
    User::WaitForRequest(status, iTimerStatus);
    TS_ASSERT_EQUALS(iTimerStatus.Int(), KRequestPending);
    TS_ASSERT_EQUALS(status.Int(), KErrNone);
    }

void CTestConUiTerm::testShowCursor()
    {
    iTerminal->ShowCursorL();
    iTerminal->WriteL(_L("Cursor is visible. Press any key if true..."));
    TConsoleKey key;
    TRequestStatus status = KRequestPending;
    iTerminal->ReadKey(key, status);
    User::WaitForRequest(status, iTimerStatus);
    TS_ASSERT_EQUALS(iTimerStatus.Int(), KRequestPending);
    TS_ASSERT_EQUALS(status.Int(), KErrNone);
    }

void CTestConUiTerm::testSetPos()
    {
    /*
     * C   s
     *  R s
     *   0
     *  r S
     * c   S
     */
    iTerminal->SetPosL(TPoint(0, 4));
    iTerminal->WriteL(_L("c"));
    iTerminal->SetPosL(TPoint(1, 3));
    iTerminal->WriteL(_L("r"));
    iTerminal->SetPosL(TPoint(2, 2));
    iTerminal->WriteL(_L("o"));
    iTerminal->SetPosL(TPoint(3, 1));
    iTerminal->WriteL(_L("s"));
    iTerminal->SetPosL(TPoint(4, 0));
    iTerminal->WriteL(_L("s"));
    iTerminal->SetPosL(TPoint(0, 0));
    iTerminal->WriteL(_L("C"));
    iTerminal->SetPosL(TPoint(1, 1));
    iTerminal->WriteL(_L("R"));
    iTerminal->SetPosL(TPoint(2, 2));
    iTerminal->WriteL(_L("0"));
    iTerminal->SetPosL(TPoint(3, 3));
    iTerminal->WriteL(_L("S"));
    iTerminal->SetPosL(TPoint(4, 4));
    iTerminal->WriteL(_L("S"));
    iTerminal->SetPosL(TPoint(0, 5));
    iTerminal->WriteL(_L("Press any key if below matches above\r\n"));
    iTerminal->WriteL(_L("C   s\r\n"));
    iTerminal->WriteL(_L(" R s \r\n"));
    iTerminal->WriteL(_L("  0  \r\n"));
    iTerminal->WriteL(_L(" r S \r\n"));
    iTerminal->WriteL(_L("c   S\r\n"));
    TConsoleKey key;
    TRequestStatus status = KRequestPending;
    iTerminal->ReadKey(key, status);
    User::WaitForRequest(status, iTimerStatus);
    TS_ASSERT_EQUALS(iTimerStatus.Int(), KRequestPending);
    TS_ASSERT_EQUALS(status.Int(), KErrNone);
    }

void CTestConUiTerm::testClearSurface()
    {
    iTerminal->WriteL(_L("Disregard next line and dont press anything\r\n"));
    iTerminal->ClearSurfaceL();
    iTerminal->WriteL(_L("Press any key..."));
    TConsoleKey key;
    TRequestStatus status = KRequestPending;
    iTerminal->ReadKey(key, status);
    User::WaitForRequest(status, iTimerStatus);
    TS_ASSERT_EQUALS(iTimerStatus.Int(), KRequestPending);
    TS_ASSERT_EQUALS(status.Int(), KErrNone);
    }

void CTestConUiTerm::testEraseToEndOfLine()
    {
    iTerminal->WriteL(_L("Press any key. Err.. Don't press anything"));
    iTerminal->SetPosL(TPoint(13, 0));
    iTerminal->EraseToEndOfLineL();
    TConsoleKey key;
    TRequestStatus status = KRequestPending;
    iTerminal->ReadKey(key, status);
    User::WaitForRequest(status, iTimerStatus);
    TS_ASSERT_EQUALS(iTimerStatus.Int(), KRequestPending);
    TS_ASSERT_EQUALS(status.Int(), KErrNone);
    }

void CTestConUiTerm::testSetForeground()
    {
    iTerminal->SetForegroundL(ConUiDef::EBlack);
    iTerminal->WriteL(_L("black "));
    iTerminal->SetForegroundL(ConUiDef::EBlue);
    iTerminal->WriteL(_L("blue "));
    iTerminal->SetForegroundL(ConUiDef::ECyan);
    iTerminal->WriteL(_L("cyan "));
    iTerminal->SetForegroundL(ConUiDef::EGreen);
    iTerminal->WriteL(_L("magenta "));
    iTerminal->SetForegroundL(ConUiDef::ERed);
    iTerminal->WriteL(_L("red "));
    iTerminal->SetForegroundL(ConUiDef::EWhite);
    iTerminal->WriteL(_L("white "));
    iTerminal->SetForegroundL(ConUiDef::EMagenta);
    iTerminal->WriteL(_L("magenta "));
    iTerminal->SetForegroundL(ConUiDef::EYellow);
    iTerminal->WriteL(_L("yellow\r\n"));
    iTerminal->SetForegroundL(ConUiDef::ENoColor);
    iTerminal->WriteL(_L("Press any key if you can see correct colors"));
    TConsoleKey key;
    TRequestStatus status = KRequestPending;
    iTerminal->ReadKey(key, status);
    User::WaitForRequest(status, iTimerStatus);
    TS_ASSERT_EQUALS(iTimerStatus.Int(), KRequestPending);
    TS_ASSERT_EQUALS(status.Int(), KErrNone);
    }

void CTestConUiTerm::testSetBackground()
    {
    iTerminal->SetForegroundL(ConUiDef::EBlack);
    iTerminal->SetBackgroundL(ConUiDef::EBlack);
    iTerminal->WriteL(_L("black "));
    iTerminal->SetForegroundL(ConUiDef::EBlue);
    iTerminal->SetBackgroundL(ConUiDef::EBlue);
    iTerminal->WriteL(_L("blue "));
    iTerminal->SetForegroundL(ConUiDef::ECyan);
    iTerminal->SetBackgroundL(ConUiDef::ECyan);
    iTerminal->WriteL(_L("cyan "));
    iTerminal->SetForegroundL(ConUiDef::EGreen);
    iTerminal->SetBackgroundL(ConUiDef::EGreen);
    iTerminal->WriteL(_L("magenta "));
    iTerminal->SetForegroundL(ConUiDef::ERed);
    iTerminal->SetBackgroundL(ConUiDef::ERed);
    iTerminal->WriteL(_L("red "));
    iTerminal->SetForegroundL(ConUiDef::EWhite);
    iTerminal->SetBackgroundL(ConUiDef::EWhite);
    iTerminal->WriteL(_L("white "));
    iTerminal->SetForegroundL(ConUiDef::EMagenta);
    iTerminal->SetBackgroundL(ConUiDef::EMagenta);
    iTerminal->WriteL(_L("magenta "));
    iTerminal->SetForegroundL(ConUiDef::EYellow);
    iTerminal->SetBackgroundL(ConUiDef::EYellow);
    iTerminal->WriteL(_L("yellow\r\n"));
    iTerminal->SetForegroundL(ConUiDef::ENoColor);
    iTerminal->SetBackgroundL(ConUiDef::ENoColor);
    iTerminal->WriteL(_L("Press any key if you can't read color names"));
    TConsoleKey key;
    TRequestStatus status = KRequestPending;
    iTerminal->ReadKey(key, status);
    User::WaitForRequest(status, iTimerStatus);
    TS_ASSERT_EQUALS(iTimerStatus.Int(), KRequestPending);
    TS_ASSERT_EQUALS(status.Int(), KErrNone);
    }

void CTestConUiTerm::testSetBold()
    {
    iTerminal->SetBoldL(ETrue);
    iTerminal->SetForegroundL(ConUiDef::EBlack);
    iTerminal->SetBackgroundL(ConUiDef::EBlack);
    iTerminal->WriteL(_L("black "));
    iTerminal->SetBoldL(EFalse);
    iTerminal->SetBoldL(ETrue);
    iTerminal->SetForegroundL(ConUiDef::EBlue);
    iTerminal->SetBackgroundL(ConUiDef::EBlue);
    iTerminal->WriteL(_L("blue "));
    iTerminal->SetForegroundL(ConUiDef::ECyan);
    iTerminal->SetBackgroundL(ConUiDef::ECyan);
    iTerminal->WriteL(_L("cyan "));
    iTerminal->SetForegroundL(ConUiDef::EGreen);
    iTerminal->SetBackgroundL(ConUiDef::EGreen);
    iTerminal->WriteL(_L("magenta "));
    iTerminal->SetForegroundL(ConUiDef::ERed);
    iTerminal->SetBackgroundL(ConUiDef::ERed);
    iTerminal->WriteL(_L("red "));
    iTerminal->SetForegroundL(ConUiDef::EWhite);
    iTerminal->SetBackgroundL(ConUiDef::EWhite);
    iTerminal->WriteL(_L("white "));
    iTerminal->SetForegroundL(ConUiDef::EMagenta);
    iTerminal->SetBackgroundL(ConUiDef::EMagenta);
    iTerminal->WriteL(_L("magenta "));
    iTerminal->SetForegroundL(ConUiDef::EYellow);
    iTerminal->SetBackgroundL(ConUiDef::EYellow);
    iTerminal->WriteL(_L("yellow\r\n"));
    iTerminal->SetForegroundL(ConUiDef::ENoColor);
    iTerminal->SetBackgroundL(ConUiDef::ENoColor);
    iTerminal->SetBoldL(EFalse);
    iTerminal->WriteL(_L("Press any key if you can read color names"));
    TConsoleKey key;
    TRequestStatus status = KRequestPending;
    iTerminal->ReadKey(key, status);
    User::WaitForRequest(status, iTimerStatus);
    TS_ASSERT_EQUALS(iTimerStatus.Int(), KRequestPending);
    TS_ASSERT_EQUALS(status.Int(), KErrNone);
    }
